/*
ID: icerupt1
PROG: camelot
LANG: C++11
*/

/* solution
 *
 * good problem. brute force and cut.
 *
*/
#include <fstream>
#include <iostream>
#include <algorithm>
#include <queue>
#include <cstdlib>

std::ifstream fin {"camelot.in" };
std::ofstream fout{"camelot.out"};

struct position { int x; int y; };

bool operator==(position const & a, position const & b)
{
	return (a.x == b.x && a.y == b.y);
}

std::ifstream & operator>>(std::ifstream & is, position & a)
{
	char ch;
	is >> ch >> a.x;
	a.x--;
	a.y = ch - 'A';
	return is;
}

int const maxn = 32;
int const oo = 1<<27;
position knight[maxn*maxn];
int knight_dis[maxn][maxn][maxn][maxn];
int all_knight_to_pos[maxn][maxn];
int n, m, num_knight, ans = oo;
position king;

int king_move(position a, position b)
{
	return std::max(std::abs(a.x - b.x), std::abs(a.y - b.y));
}

int knight_move(position a, position b)
{
	return knight_dis[a.x][a.y][b.x][b.y];
}

bool inrange(position a)
{
	return ((0 <= a.x && a.x < n) && (0 <= a.y && a.y < m));
}

int const opt[8][2] = {{-2, -1}, {-2, 1}, {-1, 2}, {1, 2},
						{2, 1}, {2, -1}, {1, -2}, {-1, -2}};

void init_knight_dis()
{
	for (auto i = 0; i < n; i++)
		for (auto j = 0; j < m; j++) {
			bool vis[n][m];
			int dis[n][m];
			std::fill(vis[0], vis[0] + n*m, 0);
			std::fill(dis[0], dis[0] + n*m, oo);
			std::queue<position> q;
			q.push({i, j});
			vis[i][j] = true;
			dis[i][j] = 0;
			while (!q.empty()) {
				position tmp = q.front();
				q.pop();
				for (int dir = 0; dir < 8; dir++) {
					position ptmp;
					ptmp.x = tmp.x + opt[dir][0];
					ptmp.y = tmp.y + opt[dir][1];
					if (inrange(ptmp) && !vis[ptmp.x][ptmp.y]) {
						vis[ptmp.x][ptmp.y] = true;
						dis[ptmp.x][ptmp.y] = dis[tmp.x][tmp.y] + 1;
						q.push(ptmp);
					}
				}
			}
			for (auto di = 0; di < n; di++)
				for (auto dj = 0; dj < m; dj++)
					knight_dis[i][j][di][dj] = dis[di][dj];
		}
}

int direct_move_king(int x, int y)
{
	int move = king_move(king, {x, y});
	for (int i = 0; i < num_knight; i++)
		move += knight_move(knight[i], {x, y});
	return move;
}

int pick_up_king(int x, int y)
{
	int min_move = oo;
	for (auto i = 0; i < n; i++)
		for (auto j = 0; j < m; j++) {
			int tmp = king_move(king, {i, j}) + all_knight_to_pos[x][y];
			if (tmp >= ans) continue;
			int min = oo, dis = knight_move({i, j}, {x, y});
			for (int k = 0; k < num_knight; k++) {
				int tk = knight_move(knight[k], {x, y});
				min = std::min(min, knight_move(knight[k], {i, j}) + dis - tk);
			}
			tmp += min;
			min_move = std::min(min_move, tmp);
		}
	return min_move;
}

int main()
{
	fin >> n >> m;
	fin >> king;
	for (; fin >> knight[num_knight]; num_knight++);
	init_knight_dis();

	for (auto i = 0; i < n; i++)
		for (auto j = 0; j < m; j++) {
			int tmp = direct_move_king(i, j);
//			std::cout << ans << " target: " << i << ' ' << j << '\n';
			ans = std::min(ans, tmp);
			all_knight_to_pos[i][j] = tmp - king_move(king, {i, j});
		}

	for (auto i = 0; i < n; i++)
		for (auto j = 0; j < m; j++) {
			if (all_knight_to_pos[i][j] >= ans) continue;
			ans = std::min(ans, pick_up_king(i, j));
		}

	std::cout << ans << '\n';
	fout << ans << '\n';
}

